<?php


namespace app\admin\jobs;


use app\common\caches\WechatCache;
use app\common\facades\WechatPay;
use app\common\models\UserWithdraw;
use Carbon\Carbon;
use think\queue\Job;

class UserWithdrawJob
{
    public function fire(Job $job, $trade_id)
    {
        $withdraw = UserWithdraw::find($trade_id);
        // 不满足打款条件：不存在该提现订单或审核通过状态为2打款中
        if (!$withdraw || $withdraw->status != 2){
            return $job->delete();
        }
        // 尝试了3次，判断为错误
        if ($job->attempts() > 3){
            $withdraw->save([
                'status' => 0,
                'fail_reason' => '打款队列执行失败'
            ]);
            return $job->delete();
        }
        // 获取打款接口调用限频
        $limiter = WechatCache::getPayToBalanceLimit();
        if ($limiter['limit'] <= 0){
            $diff = Carbon::now()->getPreciseTimestamp(3) - $limiter['micro_time'];
            // 阻塞延迟到下一秒重置限制器
            if ($diff < 1000) usleep($diff);
            WechatCache::initPayToBalanceLimit();
        }
        // 本身消费一次
        WechatCache::decPayToBalanceLimit();
        try {
            // 执行打款任务
            $result = WechatPay::payToBalance($withdraw->openid, $withdraw->trade_no, $withdraw->amount);
            if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
                // 打款成功
                $data = [
                    'status'        => 3,
                    'back_data'     => json_encode($result),
                    'payment_no'    => $result['payment_no'],
                    'payment_time'  => Carbon::parse($result['payment_time'])->getTimestamp()
                ];
            } else {
                // 打款失败
                $data = [
                    'status'        => 0,
                    'back_data'     => json_encode($result),
                ];
                if ($result['return_code'] == 'FAIL'){
                    // 接口调用失败：网关错误
                    $data['fail_reason'] = $result['return_msg'];
                } else {
                    // 接口调用成功，业务处理失败
                    $data['fail_reason'] = $result['err_code_des'];
                }
            }
        } catch (\Exception $exception){
            $data = [
                'status'        => 0,
                'fail_reason'   => $exception->getMessage()
            ];
        }

        // 更新本条数据
        $withdraw->save($data);
        // 执行成功，删除
        $job->delete();
        return true;
    }
}
